﻿using System.Collections.ObjectModel;
using Prism.Commands;
using Prism.Events;
using System.Windows.Input;
using System.Windows;
using System.Windows.Threading;
using Prism.Mvvm;
using SoonCode.Core;
using SoonCode.FocusTest.Events;
using SoonCode.FocusTest.Models;
using SoonCode.FocusTest.Utils;
namespace SoonCode.FocusTest.ViewModels
{
    internal class TestItemEViewModel : BindableBase
    {
        private int TestItemIndex = 5;
        private RandomHelper randomHelper;
        private int tabIndex = 0;
        private TestInfo testInfo;
        private IEventAggregator aggregator;
        private int level = 1;
        private string checkKey = "";
        private string checkImg = "";
        private EventInfo questEventInfo;
        private DateTime startTime;
        private int currTime = 0;
        private DispatcherTimer timer;
        private EItemHelper lastAnswer;
        private List<ObservableCollection<EItemHelper>> questionList;
        public List<EItemHelper> allQuestion;
        private SubscriptionToken answerToken;
        private string buttonContent = "下一页";
        private string helpSoundText = "停止播放提示语";
        private bool helpIsPlay = true;
        private int member_age;
        private Visibility fiveAgeTip = Visibility.Visible;
        private Visibility twoAgeTip = Visibility.Collapsed;

        public Visibility TwoAgeTip
        {
            get { return twoAgeTip; }
            set
            {
                twoAgeTip = value;
                RaisePropertyChanged();
            }
        }
        public Visibility FiveAgeTip
        {
            get { return fiveAgeTip; }
            set
            {
                fiveAgeTip = value;
                RaisePropertyChanged();
            }
        }
        public string HelpSoundText
        {
            get { return helpSoundText; }
            set
            {
                helpSoundText = value;
                RaisePropertyChanged();
            }
        }

        public string ButtonContent
        {
            get { return buttonContent; }
            set
            {
                buttonContent = value;
                RaisePropertyChanged();
            }
        }

        public int CurrTime
        {
            get { return currTime; }
            set
            {
                currTime = value;
                RaisePropertyChanged();
            }
        }
        public string CheckImg
        {
            get { return checkImg; }
            set
            {
                checkImg = value;
                RaisePropertyChanged();
            }
        }

        public int Level
        {
            get { return level; }
            set
            {
                level = value;
                RaisePropertyChanged();
            }
        }
        private ObservableCollection<EItemHelper> itemList;
        public ObservableCollection<EItemHelper> ItemList
        {
            get { return itemList; }
            set
            {
                itemList = value;
                RaisePropertyChanged();
            }
        }

        public TestItemEViewModel(IEventAggregator aggregator)
        {
            this.aggregator = aggregator;
            if (timer == null) timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.IsEnabled = false;
            timer.Tick += Timer_Tick;
            questEventInfo = new EventInfo();
            questEventInfo.Type = "itemE";
            aggregator.GetEvent<ChangeTestEvent>().Subscribe(TestChange);
            aggregator.GetEvent<EndTestEvent>().Subscribe(() =>
            {
                timer.Stop();
                aggregator.GetEvent<StudentAnswerEvent>().Unsubscribe(answerToken);
            });
            this.aggregator.GetEvent<TestLoadEvent>().Subscribe(OnLoaded);
        }

        private void TestChange(int p)
        {
            timer.Stop();
            aggregator.GetEvent<StudentAnswerEvent>().Unsubscribe(answerToken);
        }

        private void OnLoaded(int p)
        {
            timer.Stop();
            if (p != this.TestItemIndex - 1)
            {
                this.aggregator.GetEvent<StudentAnswerEvent>().Unsubscribe(answerToken);
                return;
            }
            member_age = GlobalModel.Instance.MemberInfo.age;
            if (member_age >= 5)
            {
                randomHelper = new RandomHelper(1, 9, ",");
                FiveAgeTip = Visibility.Visible;
                TwoAgeTip = Visibility.Collapsed;
            }
            else
            {
                randomHelper = new RandomHelper(1, 11, ",");
                FiveAgeTip = Visibility.Collapsed;
                TwoAgeTip = Visibility.Visible;
            }
            this.testInfo = GlobalModel.Instance.TestInfo;
            TabIndex = 0;
            Level = 1;
            CurrTime = 0;
            CheckImg = "";
            SoundPlayer.Play("1000:item5.mp3");
            Task.Run(GenerateNumbers);
            this.answerToken = aggregator.GetEvent<StudentAnswerEvent>().Subscribe(SutdentAnswer);
        }
        private void Timer_Tick(object? sender, EventArgs e)
        {
            CurrTime = (int)(DateTime.Now - startTime).TotalSeconds;
            questEventInfo.Data["currTime"] = CurrTime;
            this.aggregator.GetEvent<QuestionChangeEvent>().Publish(questEventInfo);
            if (currTime >= 180)
            {
                SoundPlayer.PlayDing();
                timer.Stop();
                complete();
            }
        }


        private void SutdentAnswer(EventInfo payload)
        {
            if (payload == null) return;
            if (payload.Type == "itemE_Next")
            {
                NextTest();
                return;
            }
            if (payload.Type != "itemE")
            {
                return;
            }

            if (ItemList==null||ItemList.Count == 0) return;
            checkAnswer((EItemHelper)payload.Data["info"]);
        }

        private async void checkAnswer(EItemHelper info)
        { 
            int lastNumber = -1;
            if (lastAnswer!=null)
                lastNumber = lastAnswer.number;
            List<EItemHelper> items = allQuestion.Where(f => f.number > lastNumber && f.number < info.number).ToList();
            foreach (EItemHelper item in items)
            {
                if(item.key==checkKey)
                    item.color = "Red";
                item.opacity = 0.5;
            }
            bool isOk=info.key==checkKey;
            EItemHelper infoItem= ItemList[info.index];
            infoItem.color = isOk ? "Green" : "Red";
            lastAnswer = infoItem;
            
        }
        public int TabIndex
        {
            get { return tabIndex; }
            set
            {
                tabIndex = value;
                RaisePropertyChanged();
            }
        }
        public ICommand HelpCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    if (helpIsPlay)
                    {
                        SoundPlayer.Stop();
                        HelpSoundText = "播放提示语";
                        helpIsPlay = false;
                    }
                    else
                    {
                        SoundPlayer.Play("item5.mp3");
                        HelpSoundText = "停止播放提示语";
                        helpIsPlay = true;
                    }
                });
            }
        }
        public ICommand SkipCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    SoundPlayer.Stop();
                    this.aggregator.GetEvent<ChangeTestEvent>().Publish(TestItemIndex);
                });
            }
        }
        public ICommand StartCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    SoundPlayer.Stop();
                    checkKey = randomHelper.next(1);
                    if (member_age >= 5)
                    {
                        do
                        {
                            checkKey = randomHelper.next(1);
                        } while (checkKey == "1" || checkKey == "7");
                    }
                    string imgSux=member_age >= 5 ? "" : "t";
                    CheckImg = $"pack://application:,,,/Images/e{imgSux}{checkKey}.png";
                    startTime = DateTime.Now;
                    TabIndex = 1;
                    lastAnswer = null;
                    timer.Start();
                    Test();
                });
            }
        }

        public ICommand AnswerErrorCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    timer.Stop();
                    complete();
                });
            }
        }
        public ICommand AnswerRightCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    NextTest();
                });
            }
        }

        private void NextTest()
        {
            if (Level >= 4)
            {
                timer.Stop();
                complete();
                return;
            }
            Level++;
            if (Level >= 4)
            {
                ButtonContent = "提交";
            }
            Test();

        }
        private void complete()
        {
            this.ItemList.Clear();
            int line = 0;
            testInfo.data[TestItemIndex - 1].item_score = "0";
            testInfo.data[TestItemIndex].item_score = "0";
            int err = allQuestion.Where(f => f.color == "Red").Count();
            int rightRatio = 0;
            if (lastAnswer!=null)
            {
                line = lastAnswer.line + 1;
                rightRatio = (int)((double)(line * 15 - err) / (line * 15) * 100);
                testInfo.data[TestItemIndex - 1].item_score = rightRatio + ""; //视觉分辨
                testInfo.data[TestItemIndex].item_score = (int)((double)line / 44 * 100) + ""; //视觉广度
            }
            DialogUtil.Show(aggregator, $"通过行数=（{line}）行，正确率=（{rightRatio}）%，本项结束，进入下一项");
            this.aggregator.GetEvent<ChangeTestEvent>().Publish(TestItemIndex);
        }

        private async void GenerateNumbers()
        {
            questionList = new List<ObservableCollection<EItemHelper>>();
            allQuestion = new List<EItemHelper>();
            string imgSuf = member_age >= 5 ? "" : "t";
            for (int p = 0; p < 4; p++)
            {
                ObservableCollection<EItemHelper> items = new ObservableCollection<EItemHelper>();
                string numberStr = randomHelper.next(165);
                string [] numbers= numberStr.Split(',');
                for (int i = 0; i < numbers.Length; i++)
                {
                    EItemHelper helper = new EItemHelper();
                    helper.img = $"pack://application:,,,/Images/e{imgSuf}{numbers[i]}.png";
                    helper.key = numbers[i].ToString();
                    helper.line = p*11+i/15 ;
                    helper.number = p*165+i;
                    helper.index = i;
                    items.Add(helper);
                    allQuestion.Add(helper);
                }
                questionList.Add(items);
            }

        }
        private async void Test()
        {
            ItemList = questionList[Level - 1];
            EventInfo info = new EventInfo() { Type = "itemE" };
            info.Data["checkKey"] = checkKey;
            info.Data["data"] = ItemList;
            info.Data["level"] = Level;
            this.aggregator.GetEvent<LevelUpdateEvent>().Publish(info);
        }
    }

    public class EItemHelper : BindableBase
    {
        private string _color = "";
        public string color
        {
            get { return _color; }
            set
            {
                _color = value;
                RaisePropertyChanged();
            }
        }

        private string _selectColor = "";

        public string selectColor
        {
            get { return _selectColor; }
            set
            {
                _selectColor= value;
                RaisePropertyChanged();
            }
        }

        private double _opacity = 1;
        public string img { get; set; }
        public string key { get; set; }
        public int index { get; set; }
        public int line { get; set; }
        public int number { get; set; }
        public double opacity
        {
            get { return _opacity;}
            set
            {
                _opacity=value;
                RaisePropertyChanged();
            }
        }
    }
}
